fix(cluster): resolve DNS failures on systemd-resolved hosts#478
fix(cluster): resolve DNS failures on systemd-resolved hosts#478brianwtaylor wants to merge 1 commit intoNVIDIA:mainfrom
Conversation
|
All contributors have signed the DCO ✍️ ✅ |
|
I have read the DCO document and I hereby sign the DCO. |
| if std::path::Path::new("/run/systemd/resolve/resolv.conf").exists() { | ||
| b.push( | ||
| "/run/systemd/resolve/resolv.conf:/run/systemd/resolve/resolv.conf:ro" | ||
| .to_string(), | ||
| ); | ||
| } | ||
| b |
There was a problem hiding this comment.
I'm just a little worried about mounting existing system files into the cluster container (this would be the first time we do it).
How about as an alternative approach we sniff the resolvers from the boostrap crate and then pass them into the cluster container as parameters.
There was a problem hiding this comment.
let me explore this, i have some qa going right now as well. happy to chat to ensure this change aligns with your standards.
update: great call out on extending the existing architecture
|
@drew after your feedback, here is a breakdown of the DNS FLOW — BEFORE vs AFTER I also did some hardware validation with these changes, below is a breakdown of the validation topology i used. OPENSHELL DNS FIX (PR #478) — VALIDATION TOPOLOGY WHAT EACH NODE PROVED |
0079604 to
0218226
Compare
|
sorry trying not to rush with this fix. |
Docker's embedded DNS at 127.0.0.11 is only reachable from the container's own network namespace. k3s pods in child namespaces cannot reach it, causing silent DNS failures on Ubuntu and other systemd-resolved hosts where /etc/resolv.conf contains 127.0.0.53. Sniff upstream DNS resolvers from the host in the Rust bootstrap crate by reading /run/systemd/resolve/resolv.conf (systemd-resolved only — intentionally does NOT read /etc/resolv.conf to avoid bypassing Docker Desktop's DNAT proxy on macOS/Windows). Filter loopback addresses (127.x.x.x and ::1) and pass the result to the container as the UPSTREAM_DNS env var. Skip DNS sniffing for remote deploys where the local host's resolvers would be wrong. The entrypoint checks UPSTREAM_DNS first, falling back to /etc/resolv.conf inside the container for manual launches. This follows the existing pattern used by registry config, SSH gateway, GPU support, and image tags. Closes #437 Signed-off-by: Brian Taylor <brian.taylor818@gmail.com>
0218226 to
106be9d
Compare
@drew thank you for approving my vouch, had this brewing as a small fix for the repo, look like this change could help some folks. doing a qa pass for this change, will add a visual diagram or two as well.
Summary
Closes #437
Related: #415
Changes
crates/openshell-bootstrap/src/docker.rs— Bind-mount/run/systemd/resolve/resolv.conf(read-only) into the container when the path exists on the host. Skipped on macOS/Windows where the path doesn't exist.deploy/docker/cluster-entrypoint.sh— Addget_upstream_resolvers()that extracts non-loopback nameservers from the mounted systemd-resolved config (or falls back to/etc/resolv.conf). When upstream resolvers are found, write them directly to the k3s resolv.conf instead of attempting the DNAT proxy. Also improves DNS verification logging on failure.Root Cause
Docker's embedded DNS at
127.0.0.11is only reachable from the container's own network namespace. The existing DNAT rules forward to this loopback address, but k3s pods run in child network namespaces where the forwarded packets are dropped as martian packets. On systemd-resolved hosts,/etc/resolv.confcontains127.0.0.53(another loopback), so the fallback also fails silently.Testing
cgroupns=host)Automated Tests
Checklist